import re
from collections import defaultdict


# 读取C++头文件内容
def read_file(file_path):
    with open(file_path, "r", encoding="utf-8") as file:
        return file.read()


# 不能提取 函数签名后缀带有 const  override关键字的成员函数,此时需要修改正则表达式
# 也不能提取类中嵌套类的成员函数
def parse_member_functions(class_content):
    # 提取成员函数的正则表达式模式（不包含多行注释）
    pattern = r"(?<!/\*)\s*(?:.+?\s+.+?\([\s\S]*?\).*?(?:;\s*|=\s*0\s*;))(?!.*\*/)"

    remove_pattern = r"/\*|\*/"
    # remove_pattern = r"\\\\[n|t|]"
    # 匹配并提取成员函数信息（不包含多行注释）
    matches = re.findall(pattern, class_content, re.MULTILINE)
    member_funcs = []
    # 输出修饰词和完整的函数签名（不包含多行注释和"*/"），去掉换行符"\n"
    for match in matches:
        function_signature = match.strip()
        function_signature = re.sub(remove_pattern, "", function_signature)
        function_signature = function_signature.replace("\n\t", "")
        print(function_signature)
        member_funcs.append(function_signature)
    return member_funcs


# 解析成员函数注释
def parse_member_functions_notes(header_content):
    # 正则表达式匹配注释中的成员函数描述
    comment_pattern = re.compile(r"/\*\*(.*?)\*/", re.DOTALL)
    # 正则表达式匹配@brief、@param、@return和@details
    detail_patterns = {
        "brief": r"@brief\s+(.*)",
        "param": r"@param\s+\[(.*)\]\s+(.*)",
        "return": r"@return\s+(.*)",
        "details": r"@details\s+(.*)",
    }

    # 找到所有匹配的成员函数注释块
    comments = comment_pattern.findall(header_content)

    for comment in comments:
        output_str = re.sub(r"(?<=\n).*?(?=@)", "", comment, flags=re.DOTALL)

        lines = output_str.split("\n")
        # 移除第一个元素和最后一个元素
        lines.pop(0)
        # 过滤掉文件注释
        if lines and "@file" in lines[0]:
            continue

        function_info = {}

        for detail_name, pattern in detail_patterns.items():
            for line in lines:

                if line.startswith(f"@{detail_name}"):
                    match = re.search(pattern, line, re.DOTALL)
                    if match:
                        if detail_name == "param":
                            function_info["param"] = match.group(2)  # 参数名
                        else:
                            function_info[detail_name] = match.group(1).strip()
                        break

        # 格式化输出
        formatted_info = f""
        if "brief" in function_info:
            formatted_info += f"功能：{function_info['brief']}\n"
        if "param" in function_info:
            formatted_info += f"参数：{function_info['param']}\n"
        if "return" in function_info:
            formatted_info += f"返回值：{function_info['return']}\n"
        if "details" in function_info:
            formatted_info += f"处理流程：{function_info['details']}\n"

        yield formatted_info


# 解析C++头文件中的类定义
def parse_classes(header_content):
    # 正则表达式匹配类定义
    class_pattern = re.compile(
        r"class\s+(\w+)\s*(:\s*public\s+\w+)?\s*\{(.*?)\};", re.DOTALL
    )

    # 使用 defaultdict 以便自动创建缺失的键
    classes = defaultdict(str)

    # 找到所有匹配的类定义
    matches = class_pattern.finditer(header_content)

    for match in matches:
        class_name = match.group(1)
        classes[class_name] += match.group(3).strip()  # 添加类内容

    return dict(classes)  # 转换为普通字典


# 主函数
def main():
    file_path = "./include/ExperiMsgProtocol.h"  # C++头文件路径
    header_content = read_file(file_path)

    classes = parse_classes(header_content)

    # 以类为单位 进行解析
    for class_name, class_content in classes.items():
        print(f"--------------------类名: {class_name}---------------------")

        # 解析类函数的注释
        member_notes = list(parse_member_functions_notes(class_content))

        # 解析类函数的签名
        member_funcs = parse_member_functions(class_content)
        # 输出格式化后的成员函数信息
        for i, func_info in enumerate(member_notes, start=0):
            print(f"序号：{i}")
            print(f"名称：{member_funcs[i]}")
            print(f"访问类别：public")
            print(func_info)


if __name__ == "__main__":
    main()
